package com.cloudbroker.bcs.platform.ltb.common.action;

import com.alibaba.fastjson.JSON;
import com.cloudbroker.bcs.common.constants.BasicErrorCodes;
import com.cloudbroker.bcs.common.util.*;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.HSBCPSFields;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.type.UserCacheFreshType;
import com.cloudbroker.bcs.platform.ltb.common.config.ConfigValues;
import com.cloudbroker.bcs.platform.ltb.common.constant.SysContants;
import com.cloudbroker.bcs.platform.ltb.common.constant.type.UploadType;
import com.cloudbroker.bcs.platform.ltb.common.ext.annotation.SaveLog;
import com.cloudbroker.bcs.platform.ltb.common.extservice.store.StoreServiceFactory;
import com.cloudbroker.bcs.platform.ltb.common.util.*;
import com.cloudbroker.bcs.platform.ltb.common.util.SessionHelper;
import com.cloudbroker.bcs.platform.ltb.common.util.qrcode.QrCodeUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;

import static com.cloudbroker.bcs.platform.ltb.bizapi.constants.HSBCPSErrorCodes.CommonErr.*;

/**
 * Created by xuyn15828 on 2016/3/16.
 */
@Controller
public class FileController {
    private String platform;
    private static final Logger logger = LoggerFactory.getLogger(FileController.class);
    private static final String FILE_NAME_SEPTUM = "_";
    private static final String NO_LOGIN_TOKEN = DigestUtil.MD5(DigestUtil.SHA512("noLogin".getBytes()).getBytes());

    /*@Resource
    private FileT2BizService fileT2;*/

    @ResponseBody
    @RequestMapping(value = "/func_file_upload",produces="application/json;charset=UTF-8")
    public Map<String, Object> uploadFile(
            @RequestParam(value = "type") String type,
            @RequestParam(required=false ,value = "is_custom") String is_custom,
            MultipartHttpServletRequest request) {
        try {
            logger.error("upload parameter : " + JSON.toJSONString(request.getParameterMap()));
            String accessToken = request.getParameter(HSBCPSFields.USER_TOKEN);
            com.cloudbroker.bcs.platform.ltb.common.util.SessionHelper sessionHelper = SessionHelper.getInstance();
//            String accessTokenKey = sessionHelper.getAccess_tokenKey(accessToken);
            if ( !sessionHelper.exist(accessToken)) {
                return VOUtil.genErrorResult(BasicErrorCodes.NOT_LOGGED);
            }
            Map map = JSON.parseObject(com.cloudbroker.bcs.platform.ltb.common.util.CacheHelper.getInstance().get(accessToken),Map.class);
            Map brokerVO_map = (Map) map.get("brokerVO");
            Map user_map = (Map) brokerVO_map.get("user");

            MultipartFile multipartFile = request.getFile(HSBCPSFields.FILE);
            String fileMark = ValueUtil.getString(request.getParameter(HSBCPSFields.FILE_MARK), "");
            String customerId = request.getParameter(HSBCPSFields.CUSTOMER_ID);
            if (customerId == null || "".equals(customerId)) {
                customerId = SysContants.UPLOAD_WITHOUT_CUSTOMERID;
            }
            if (null == multipartFile || multipartFile.getSize() == 0) {
                return VOUtil.genErrorResult(FILE_TRANS_ERROR, "文件传输失败");
            } else if (!UploadType.typeExists(type)) {
                return VOUtil.genErrorResult(UPLOAD_FILE_TYPE_ERROR, "文件类型不存在");
            }
            Set<String> acceptFormatSet = UploadType.collectType(type);
            String fileType = IOUtil.getFileType(multipartFile.getInputStream());
            if (!acceptFormatSet.contains(fileType)) {
                return VOUtil.genErrorResult(UPLOAD_FILE_TYPE_ERROR, "文件上传仅支持 : " + acceptFormatSet + "后缀格式");
            }

            String classpath = EnvironmentUtils.getClasspathRoot();
            byte[] b = FormatUtil.wavToMp3(multipartFile.getInputStream(), fileType, classpath);
            InputStream ips = IOUtil.mark(IOUtil.bytesToStream(b));
            fileType = IOUtil.getFileType(IOUtil.reset(ips));

            String filename = "";
            String oss_id = brokerVO_map.get("company_id").toString() + "-" + brokerVO_map.get("sendercomp_id").toString() + "-" + user_map.get("user_id");
            if(StringUtils.isNotBlank(is_custom) && is_custom.equals("1")) {
                filename = oss_id;
            } else if (type.equals("audio")){
                filename = UUID.randomUUID().toString().replaceAll("-", "");
                String timeLong = request.getParameter(HSBCPSFields.TIMELONG);
                filename = oss_id + FILE_NAME_SEPTUM + System.currentTimeMillis()
                        + FILE_NAME_SEPTUM + filename.substring(0, 5)
                        + FILE_NAME_SEPTUM + timeLong;
            } else{
                filename = UUID.randomUUID().toString().replaceAll("-", "");
                String secret = type.equals("idcard") ? "1" : "0";
                filename = oss_id + FILE_NAME_SEPTUM
                        + System.currentTimeMillis() + FILE_NAME_SEPTUM + filename.substring(0, 5);
            }

            b = CompressUtil.compress(ips, (long) b.length, fileType, type, classpath);
            StoreServiceFactory.getInstance().getStoreService().uploadFile(filename, b);
            Map<String, Object> resMap = new HashMap<>();
            resMap.put(HSBCPSFields.FILE_MARK, fileMark);
            resMap.put(HSBCPSFields.OSS_ID, filename);
            resMap.put(HSBCPSFields.OSS_PREFIX, ConfigValues.getInterfaceOssAddr());
            resMap.put(HSBCPSFields.FORMAT, fileType);
            resMap.put(HSBCPSFields.SIZE, b.length);
            Map<String, Object> ret = VOUtil.genEmptyResult();
            resMap = VOUtil.setSuccessResult(resMap);
            ret.put("data", resMap);
            return ret;
        } catch (Exception e) {
            logger.error("upload file error ", e);
        }
        return VOUtil.genCommonErrorResult();
    }

    @RequestMapping("/func_file_download/{file_name}/{user_token}")
    public void downloadFile(@PathVariable("file_name") String file_name,
            @PathVariable("user_token") String access_token, HttpServletResponse response) throws IOException {
        OutputStream ops = response.getOutputStream();
        InputStream ips = null;
        try {
            com.cloudbroker.bcs.platform.ltb.common.util.SessionHelper sessionHelper = SessionHelper.getInstance();
            String accessTokenKey = sessionHelper.getAccess_tokenKey(access_token);
            if(!sessionHelper.exist(access_token)){
//            if (!access_token.equals(NO_LOGIN_TOKEN) && !sessionHelper.exist(access_token)) {
                String downloadIgnoreCheckFilename = ConfigValues.getDownloadIgnoreCheckFilename();
                Set<String> filenameSet = new HashSet<>(Arrays.asList(downloadIgnoreCheckFilename.split(",")));
                if (!filenameSet.contains(file_name)) {
                    ops.write(JSON.toJSONString(VOUtil.genErrorResult(BasicErrorCodes.NOT_LOGGED, "未登录或已超时"))
                            .getBytes("utf-8"));
                    return;
                }
            }
            ips = StoreServiceFactory.getInstance().getStoreService().downloadFile(file_name);
            if (ips == null) {
                ops.write(JSON.toJSONString(VOUtil.genErrorResult(FILE_NOT_FOUND, "文件不存在")).getBytes("UTF-8"));
                return;
            }
            IOUtils.copy(ips, ops);
        } catch (Exception e) {
            logger.error("download file error ", e);
        } finally {
            IOUtil.close(ips);
            IOUtil.close(ops);
        }
    }

    public String getPlatform() {
        return platform;
    }

    public void setPlatform(String platform) {
        this.platform = platform;
    }



    /**
     * 二维码生成
     * @param request
     * @param jsonpcallback
     * @return
     */
    @ResponseBody
    @RequestMapping("/func_qrcode_generate")
    @SaveLog(remark = "二维码生成")
    public Map<String, Object> funcQrcodeGenerate(HttpServletRequest request, String jsonpcallback){
        String customerId = request.getParameter(HSBCPSFields.CUSTOMER_ID);
        if (customerId == null || "".equals(customerId)) {
            customerId = SysContants.UPLOAD_WITHOUT_CUSTOMERID;
        }
        /*读取生成内容*/
        String content = request.getParameter("content");
        InputStream ips = null;
        if(StringUtil.isEmpty(content))
        {
            return VOUtil.genErrorResult("二维码内容不能为空");
        }
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        try {
            BufferedImage bufferedImage = QrCodeUtil.createImage(content, null, true);
            ImageIO.write(bufferedImage,"jpg",byteArrayOutputStream);
            byte[] b = byteArrayOutputStream.toByteArray();
            String classpath = EnvironmentUtils.getClasspathRoot();
            return uploadFileFromBytes(b,ips,"img",customerId,"",classpath);

        } catch (IOException e) {
            logger.error("write bufferedImage to byteArrayOutputStream error ", e);
        }
        finally {
            IOUtil.close(byteArrayOutputStream);
            IOUtil.close(ips);
        }
        return VOUtil.genCommonErrorResult();
    }

    private Map<String, Object> uploadFileFromBytes(byte[] b,InputStream ips,String type,
                                                    String customerId,String fileMark,String classpath)
    {
        ips = IOUtil.mark(IOUtil.bytesToStream(b));
        String fileType = IOUtil.getFileType(IOUtil.reset(ips));

        String filename = UUID.randomUUID().toString().replaceAll("-", "");
        String secret = type.equals("idcard") ? "1" : "0";
        filename = customerId + FILE_NAME_SEPTUM + fileType + FILE_NAME_SEPTUM + secret + FILE_NAME_SEPTUM
                + System.currentTimeMillis() + FILE_NAME_SEPTUM + filename.substring(0, 5);

        b = CompressUtil.compress(ips, (long) b.length, fileType, type, classpath);
        try {
            StoreServiceFactory.getInstance().getStoreService().uploadFile(filename, b);
        } catch (Exception e) {
            logger.error("upload file error ", e);
        }
        Map<String, Object> resMap = new HashMap<>();
        resMap.put(HSBCPSFields.FILE_MARK, fileMark);
        resMap.put(HSBCPSFields.OSS_ID, filename);
        resMap.put(HSBCPSFields.OSS_PREFIX, ConfigValues.getInterfaceOssAddr());
        resMap.put(HSBCPSFields.FORMAT, fileType);
        resMap.put(HSBCPSFields.SIZE, b.length);
        Map<String, Object> ret = VOUtil.genEmptyResult();
        resMap = VOUtil.setSuccessResult(resMap);
        ret.put("data", resMap);
        return ret;
    }

    @ResponseBody
    @RequestMapping(value = "/manage/func_file_upload",produces="application/json;charset=UTF-8")
    public Map<String, Object> publicManageUploadFile(
            @RequestParam(value = "type") String type,
            MultipartHttpServletRequest request) {
        try {
            logger.error("upload parameter : " + JSON.toJSONString(request.getParameterMap()));
            String company_id = request.getParameter("company_id");
            if(StringUtil.isEmpty(company_id))
            {
                return VOUtil.genErrorResult("company_id不能为空");
            }
            MultipartFile multipartFile = request.getFile(HSBCPSFields.FILE);
            String fileMark = ValueUtil.getString(request.getParameter(HSBCPSFields.FILE_MARK), "");
            String customerId = request.getParameter(HSBCPSFields.CUSTOMER_ID);
            if (null == multipartFile || multipartFile.getSize() == 0) {
                return VOUtil.genErrorResult(FILE_TRANS_ERROR, "文件传输失败");
            } else if (!UploadType.typeExists(type)) {
                return VOUtil.genErrorResult(UPLOAD_FILE_TYPE_ERROR, "文件类型不存在");
            }
            Set<String> acceptFormatSet = UploadType.collectType(type);
            String fileType = IOUtil.getFileType(multipartFile.getInputStream());
            if (!acceptFormatSet.contains(fileType)) {
                return VOUtil.genErrorResult(UPLOAD_FILE_TYPE_ERROR, "文件上传仅支持 : " + acceptFormatSet + "后缀格式");
            }

            String classpath = EnvironmentUtils.getClasspathRoot();
            byte[] b = FormatUtil.wavToMp3(multipartFile.getInputStream(), fileType, classpath);
            InputStream ips = IOUtil.mark(IOUtil.bytesToStream(b));
            fileType = IOUtil.getFileType(IOUtil.reset(ips));

            String filename = "";
            String oss_id = "publicManage" + FILE_NAME_SEPTUM + company_id;
            filename = UUID.randomUUID().toString().replaceAll("-", "");
            filename = oss_id + FILE_NAME_SEPTUM + System.currentTimeMillis()
                    + FILE_NAME_SEPTUM + filename.substring(0, 5);

//            b = CompressUtil.compress(ips, (long) b.length, fileType, type, classpath);
            StoreServiceFactory.getInstance().getStoreService().uploadFile(filename, b);
            Map<String, Object> resMap = new HashMap<>();
            resMap.put(HSBCPSFields.FILE_MARK, fileMark);
            resMap.put(HSBCPSFields.OSS_ID, filename);
            resMap.put(HSBCPSFields.OSS_PREFIX, ConfigValues.getInterfaceOssAddr());
            resMap.put(HSBCPSFields.FORMAT, fileType);
            resMap.put(HSBCPSFields.SIZE, b.length);
            Map<String, Object> ret = VOUtil.genEmptyResult();
            resMap = VOUtil.setSuccessResult(resMap);
            ret.put("data", resMap);
            return ret;
        } catch (Exception e) {
            logger.error("upload file error ", e);
        }
        return VOUtil.genCommonErrorResult();
    }
    @RequestMapping("/manage/func_file_download/{file_name}")
    public void publicManageDownloadFile(@PathVariable("file_name") String file_name, HttpServletResponse response) throws IOException {
        OutputStream ops = response.getOutputStream();
        InputStream ips = null;
        try {
            ips = StoreServiceFactory.getInstance().getStoreService().downloadFile(file_name);
            if (ips == null) {
                ops.write(JSON.toJSONString(VOUtil.genErrorResult(FILE_NOT_FOUND, "文件不存在")).getBytes("UTF-8"));
                return;
            }
            IOUtils.copy(ips, ops);
        } catch (Exception e) {
            logger.error("download file error ", e);
        } finally {
            IOUtil.close(ips);
            IOUtil.close(ops);
        }
    }

}
